﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Onetube.Entities.PlayListItemQuery;
using Onetube.Models.SearchVideo;
using Onetube.Providers.Interfaces;
using System.Diagnostics;

namespace Onetube.Providers
{
    public class YoutubePlayListItemProvider : IYoutubePlayListItemProvider
    {
        private YoutubeChannelProvider channelProvider;
        private YoutubeVideoProvider videoProvider;

        public async Task<Models.SearchVideo.SearchVideoResult> GetMyWatchHistoryAsync(string token, string maxResults, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.WatchHistory);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }

                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }

                    result = null;
                }
            }
           
            return videoResult;
        }

        public async Task<Models.SearchVideo.SearchVideoResult> GetMyWatchHistoryNextPageAsync(string token, string maxResults, string nextPageToken, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.WatchHistory);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&pageToken={0}", nextPageToken);
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    count = 0;
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyWatchLaterAsync(string token, string maxResults, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.WatchLater);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyWatchLaterNextPageAsync(string token, string maxResults, string nextPageToken, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.WatchLater);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&pageToken={0}", nextPageToken);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= result.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }
      
        public async Task<SearchVideoResult> GetMyFavoritesAsync(string token, string maxResults, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Favorites);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyFavoritesNextPageAsync(string token, string maxResults, string nextPageToken, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Favorites);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&pageToken={0}", nextPageToken);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyLikesAsync(string token, string maxResults, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Likes);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyLikesNextPageAsync(string token, string maxResults, string nextPageToken, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Likes);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&pageToken={0}", nextPageToken);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyUploadsAsync(string token, string maxResults, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Uploads);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetMyUploadsNextPageAsync(string token, string maxResults, string nextPageToken, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            if (mychannel != null)
            {
                StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                petitionUri.AppendFormat("part={0}", "contentDetails");
                petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Uploads);
                petitionUri.AppendFormat("&mine={0}", "true");
                petitionUri.AppendFormat("&maxResults={0}", maxResults);
                petitionUri.AppendFormat("&pageToken={0}", nextPageToken);
                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
                var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                request.Headers["Authorization"] = "Bearer  " + token;
                var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
                if (result != null)
                {
                    videoResult.nextPageToken = result.NextPageToken;
                    videoProvider = new YoutubeVideoProvider();
                    int count = 0;
                    string videoIds = string.Empty;
                    string channelIds = string.Empty;
                    for (int i = 0; i <= result.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = result.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= result.Items.Count())
                            {
                                videoIds += item.ContentDetails.VideoId;
                            }
                            else
                            {
                                videoIds += item.ContentDetails.VideoId + ",";
                            }
                        }
                    }
                    var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                    count = 0;
                    if (videoDataList != null)
                    {
                        for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                        {
                            count++;
                            var item = videoDataList.Items.ElementAt(i);
                            if (item.Id != null)
                            {
                                if (count >= videoDataList.Items.Count())
                                {
                                    channelIds += item.Snippet.ChannelId;
                                }
                                else
                                {
                                    channelIds += item.Snippet.ChannelId + ",";
                                }
                            }
                        }
                    }

                    var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                    if (channelDataList != null)
                    {
                        if (videoDataList != null)
                        {
                            foreach (var videoItem in videoDataList.Items)
                            {
                                var dataItem = new Onetube.Models.SearchVideo.Item();

                                dataItem.etag = videoResult.etag;
                                dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                                dataItem.kind = videoItem.Kind;
                                var snippet = new Onetube.Models.SearchVideo.Snippet();
                                snippet.channelId = videoItem.Snippet.ChannelId;
                                snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                                snippet.description = videoItem.Snippet.Description;
                                snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                                snippet.publishedAt = videoItem.Snippet.PublishedAt;
                                snippet.title = videoItem.Snippet.Title;
                                snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                                {
                                    @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                    high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                    medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                                };
                                var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                                var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                                if (correspondVideo != null)
                                {
                                    contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                    contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                    contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                    contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                    contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                                }

                                snippet.contentDetails = contentDetails;

                                var statistics = new Onetube.Models.SearchVideo.Statistics();
                                statistics.commentCount = correspondVideo.Statistics.CommentCount;
                                statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                                statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                                statistics.likeCount = correspondVideo.Statistics.LikeCount;
                                statistics.viewCount = correspondVideo.Statistics.ViewCount;

                                snippet.statistics = statistics;
                                dataItem.snippet = snippet;
                                if (channelDataList != null)
                                {
                                    if (channelDataList.Items.Any())
                                    {
                                        var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                        if (correspondChannel != null)
                                        {
                                            dataItem.snippet.channelDetails = new ChannelSnippet();
                                            dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                            dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                            dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                            {
                                                @default = new Models.SearchVideo.Default
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Default.Url
                                                },
                                                high = new Models.SearchVideo.High
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.High.Url
                                                },
                                                medium = new Models.SearchVideo.Medium
                                                {
                                                    url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                                }
                                            };
                                            dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                        }
                                    }
                                }
                                videoResult.items.Add(dataItem);
                            }
                        }
                        videoDataList = null;
                        channelDataList = null;
                        videoIds = null;
                        channelIds = null;
                    }
                    result = null;
                }
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetVideosFromPlayListAsync(string maxResults, string playlistId, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
          
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

            petitionUri.AppendFormat("part={0}", "contentDetails");
            petitionUri.AppendFormat("&playlistId={0}", playlistId);
                
            petitionUri.AppendFormat("&maxResults={0}", maxResults);
             
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
            var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
               
            var result = await ResolveRequest(petitionUri.ToString(), taskCompletitionSource, cancelTask).ConfigureAwait(false);
            if (result != null)
            {
                videoResult.nextPageToken = result.NextPageToken;
                videoResult.pageInfo = new Models.SearchVideo.PageInfo();
                videoResult.pageInfo.totalResults = result.PageInfo.TotalResults;

                videoProvider = new YoutubeVideoProvider();
                int count = 0;
                string videoIds = string.Empty;
                string channelIds = string.Empty;
                for (int i = 0; i <= result.Items.Count() - 1; i++)
                {
                    count++;
                    var item = result.Items.ElementAt(i);
                    if (item.Id != null)
                    {
                        if (count >= result.Items.Count())
                        {
                            videoIds += item.ContentDetails.VideoId;
                        }
                        else
                        {
                            videoIds += item.ContentDetails.VideoId + ",";
                        }
                    }
                }
                var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                count = 0;
                if (videoDataList != null)
                {
                    for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = videoDataList.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= videoDataList.Items.Count())
                            {
                                channelIds += item.Snippet.ChannelId;
                            }
                            else
                            {
                                channelIds += item.Snippet.ChannelId + ",";
                            }
                        }
                    }
                }

                var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                if (channelDataList != null)
                {
                    if (videoDataList != null)
                    {
                        foreach (var videoItem in videoDataList.Items)
                        {
                            var dataItem = new Onetube.Models.SearchVideo.Item();

                            dataItem.etag = videoResult.etag;
                            dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                            dataItem.kind = videoItem.Kind;
                            var snippet = new Onetube.Models.SearchVideo.Snippet();
                            snippet.channelId = videoItem.Snippet.ChannelId;
                            snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                            snippet.description = videoItem.Snippet.Description;
                            snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                            snippet.publishedAt = videoItem.Snippet.PublishedAt;
                            snippet.title = videoItem.Snippet.Title;
                            snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                            {
                                @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                            };
                            var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                            var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                            if (correspondVideo != null)
                            {
                                contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                            }

                            snippet.contentDetails = contentDetails;

                            var statistics = new Onetube.Models.SearchVideo.Statistics();
                            statistics.commentCount = correspondVideo.Statistics.CommentCount;
                            statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                            statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                            statistics.likeCount = correspondVideo.Statistics.LikeCount;
                            statistics.viewCount = correspondVideo.Statistics.ViewCount;

                            snippet.statistics = statistics;
                            dataItem.snippet = snippet;
                            if (channelDataList != null)
                            {
                                if (channelDataList.Items != null && channelDataList.Items.Any())
                                {
                                    var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                    if (correspondChannel != null)
                                    {
                                        dataItem.snippet.channelDetails = new ChannelSnippet();
                                        dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                        dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                        dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                        {
                                            @default = new Models.SearchVideo.Default
                                            {
                                                url = correspondChannel.Snippet.Thumbnails.Default.Url
                                            },
                                            high = new Models.SearchVideo.High
                                            {
                                                url = correspondChannel.Snippet.Thumbnails.High.Url
                                            },
                                            medium = new Models.SearchVideo.Medium
                                            {
                                                url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                            }
                                        };
                                        dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                    }
                                }
                            }
                            videoResult.items.Add(dataItem);
                        }
                    }
                    videoDataList = null;
                    channelDataList = null;
                    videoIds = null;
                    channelIds = null;
                }
                result = null;
            }
            return videoResult;
        }

        public async Task<SearchVideoResult> GetVideosFromPlayListNextAsync(string maxResults, string playlistId, string nextPageToken, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
           
            var videoResult = new Models.SearchVideo.SearchVideoResult();
            videoResult.items = new List<Models.SearchVideo.Item>();
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

            petitionUri.AppendFormat("part={0}", "contentDetails");
            petitionUri.AppendFormat("&playlistId={0}", playlistId);
            // petitionUri.AppendFormat("&mine={0}", "true");
            petitionUri.AppendFormat("&maxResults={0}", maxResults);
            petitionUri.AppendFormat("&pageToken={0}", nextPageToken);
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
            var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
                
            var result = await ResolveRequest(petitionUri.ToString(), taskCompletitionSource, cancelTask).ConfigureAwait(false);
            if (result != null)
            {
                videoResult.nextPageToken = result.NextPageToken;
                videoProvider = new YoutubeVideoProvider();
                int count = 0;
                string videoIds = string.Empty;
                string channelIds = string.Empty;
                for (int i = 0; i <= result.Items.Count() - 1; i++)
                {
                    count++;
                    var item = result.Items.ElementAt(i);
                    if (item.Id != null)
                    {
                        if (count >= result.Items.Count())
                        {
                            videoIds += item.ContentDetails.VideoId;
                        }
                        else
                        {
                            videoIds += item.ContentDetails.VideoId + ",";
                        }
                    }
                }
                var videoDataList = await videoProvider.GeVideoInfoAsync(videoIds, "MX", cancelTask).ConfigureAwait(false);
                count = 0;
                if (videoDataList != null)
                {
                    for (int i = 0; i <= videoDataList.Items.Count() - 1; i++)
                    {
                        count++;
                        var item = videoDataList.Items.ElementAt(i);
                        if (item.Id != null)
                        {
                            if (count >= videoDataList.Items.Count())
                            {
                                channelIds += item.Snippet.ChannelId;
                            }
                            else
                            {
                                channelIds += item.Snippet.ChannelId + ",";
                            }
                        }
                    }
                }

                var channelDataList = await channelProvider.SearchChannelByIdAsync(channelIds, cancelTask).ConfigureAwait(false);
                if (channelDataList != null)
                {
                    if (videoDataList != null)
                    {
                        foreach (var videoItem in videoDataList.Items)
                        {
                            var dataItem = new Onetube.Models.SearchVideo.Item();

                            dataItem.etag = videoResult.etag;
                            dataItem.id = new Onetube.Models.SearchVideo.Id { kind = videoItem.Id, videoId = videoItem.Id };
                            dataItem.kind = videoItem.Kind;
                            var snippet = new Onetube.Models.SearchVideo.Snippet();
                            snippet.channelId = videoItem.Snippet.ChannelId;
                            snippet.channelTitle = videoItem.Snippet.ChannelTitle;
                            snippet.description = videoItem.Snippet.Description;
                            snippet.liveBroadcastContent = videoItem.Snippet.LiveBroadcastContent;
                            snippet.publishedAt = videoItem.Snippet.PublishedAt;
                            snippet.title = videoItem.Snippet.Title;
                            snippet.thumbnails = new Onetube.Models.SearchVideo.Thumbnails
                            {
                                @default = new Onetube.Models.SearchVideo.Default { url = videoItem.Snippet.Thumbnails.Default.Url },
                                high = new Onetube.Models.SearchVideo.High { url = videoItem.Snippet.Thumbnails.High.Url },
                                medium = new Onetube.Models.SearchVideo.Medium { url = videoItem.Snippet.Thumbnails.Medium.Url }
                            };
                            var contentDetails = new Onetube.Models.SearchVideo.ContentDetails();
                            var correspondVideo = videoDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Id));
                            if (correspondVideo != null)
                            {
                                contentDetails.caption = correspondVideo.ContentDetails.Caption;
                                contentDetails.definition = correspondVideo.ContentDetails.Definition;
                                contentDetails.dimension = correspondVideo.ContentDetails.Dimension;
                                contentDetails.duration = correspondVideo.ContentDetails.Duration;
                                contentDetails.licensedContent = correspondVideo.ContentDetails.LicensedContent;
                            }

                            snippet.contentDetails = contentDetails;

                            var statistics = new Onetube.Models.SearchVideo.Statistics();
                            statistics.commentCount = correspondVideo.Statistics.CommentCount;
                            statistics.dislikeCount = correspondVideo.Statistics.DislikeCount;
                            statistics.favoriteCount = correspondVideo.Statistics.FavoriteCount;
                            statistics.likeCount = correspondVideo.Statistics.LikeCount;
                            statistics.viewCount = correspondVideo.Statistics.ViewCount;

                            snippet.statistics = statistics;
                            dataItem.snippet = snippet;
                            if (channelDataList != null)
                            {
                                if (channelDataList.Items != null && channelDataList.Items.Any())
                                {
                                    var correspondChannel = channelDataList.Items.FirstOrDefault(x => x.Id.Equals(videoItem.Snippet.ChannelId));
                                    if (correspondChannel != null)
                                    {
                                        dataItem.snippet.channelDetails = new ChannelSnippet();
                                        dataItem.snippet.channelDetails.Description = correspondChannel.Snippet.Description;
                                        dataItem.snippet.channelDetails.PublishedAt = correspondChannel.Snippet.PublishedAt;
                                        dataItem.snippet.channelDetails.Thumbnails = new Models.SearchVideo.Thumbnails
                                        {
                                            @default = new Models.SearchVideo.Default
                                            {
                                                url = correspondChannel.Snippet.Thumbnails.Default.Url
                                            },
                                            high = new Models.SearchVideo.High
                                            {
                                                url = correspondChannel.Snippet.Thumbnails.High.Url
                                            },
                                            medium = new Models.SearchVideo.Medium
                                            {
                                                url = correspondChannel.Snippet.Thumbnails.Medium.Url
                                            }
                                        };
                                        dataItem.snippet.channelDetails.Title = correspondChannel.Snippet.Title;
                                    }
                                }
                            }
                            videoResult.items.Add(dataItem);
                        }
                    }
                    videoDataList = null;
                    channelDataList = null;
                    videoIds = null;
                    channelIds = null;
                }
                result = null;
            }
            return videoResult;
        }

        public async Task<bool> SetLikeAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var myChannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");
            petitionUri.AppendFormat("part={0}", "snippet");
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
            Entities.EntitiesRequest.Like.SnippetLike t1 = new Entities.EntitiesRequest.Like.SnippetLike();
            t1.snippet = new Entities.EntitiesRequest.Like.Snippet();
            t1.snippet.playlistId = myChannel.Items.First().ContentDetails.RelatedPlaylists.Likes;
            t1.snippet.resourceId = new Entities.EntitiesRequest.Like.ResourceId { kind = "youtube#video", videoId = videoId };
            DataContractJsonSerializer jsondata = new DataContractJsonSerializer(typeof(Entities.EntitiesRequest.Like.SnippetLike));
            MemoryStream mem = new MemoryStream();
            jsondata.WriteObject(mem, t1);
            string josnserdata = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
            var tcs = new TaskCompletionSource<bool>();

            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post,petitionUri.ToString());

                Debug.WriteLine(string.Format("Request Content:{0}", josnserdata));
                request.Content = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(josnserdata.ToString())));
                HttpClient client = new HttpClient();
                client.DefaultRequestHeaders.Add("Authorization", "Bearer  " + token);
                request.Content.Headers.Add("Content-Type", "application/json");
                
                System.Net.Http.HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
                var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
           
                if (response.IsSuccessStatusCode)
                {
                    tcs.SetResult(true);
                }
                else
                {
                    tcs.SetResult(false);
                }
            }
            catch (Exception ex)
            {
                tcs.SetException(ex);
            }
       
            return await tcs.Task;         
        }

        public Task<bool> SetDislikeAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            throw new NotImplementedException();
        }

        public async Task<bool> IsLikedAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

            petitionUri.AppendFormat("part={0}", "snippet");

            petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Likes);
            petitionUri.AppendFormat("&videoId={0}", videoId);
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
            
            var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
            HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
            request.Headers["Authorization"] = "Bearer  " + token;
            var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
            if (result != null)
            {
                if (result.Items != null)
                {
                    if (result.Items.Any())
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public async Task<bool> DeleteLikeAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var mychannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

            petitionUri.AppendFormat("part={0}", "snippet");

            petitionUri.AppendFormat("&playlistId={0}", mychannel.Items.FirstOrDefault().ContentDetails.RelatedPlaylists.Likes);
            petitionUri.AppendFormat("&videoId={0}", videoId);
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);

            var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
            HttpWebRequest request = HttpWebRequest.CreateHttp(petitionUri.ToString());
            request.Headers["Authorization"] = "Bearer  " + token;
            var result = await ResolveRequest(request, taskCompletitionSource, cancelTask).ConfigureAwait(false);
            if (result != null)
            {
                if (result.Items != null)
                {
                    if (result.Items.Any())
                    {
                        try
                        {
                            var playlistItem = result.Items.FirstOrDefault();
                            if (playlistItem != null)
                            {
                                petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

                                petitionUri.AppendFormat("id={0}", playlistItem.Id);

                                petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);

                                request = HttpWebRequest.CreateHttp(petitionUri.ToString());
                                request.Method = "DELETE";
                                request.Headers["Authorization"] = "Bearer  " + token;
                                var response = await request.GetResponseAsync().ConfigureAwait(false);
                               
                                return true;
                            }
                        }
                        catch (Exception)
                        {
                            return false;
                        }
                    }
                }
                return false;
            }
            return false;
        }

        public Task<bool> DeleteDislikeAsync(string token, string playListItemId, CancellationTokenSource cancelTask)
        {
            throw new NotImplementedException();
        }

        public Task<bool> IsDisLikedAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            throw new NotImplementedException();
        }

        public async Task<bool> InsertVideoToWatchLaterAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var myChannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");
            petitionUri.AppendFormat("part={0}", "snippet");
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
            Entities.EntitiesRequest.Like.SnippetLike t1 = new Entities.EntitiesRequest.Like.SnippetLike();
            t1.snippet = new Entities.EntitiesRequest.Like.Snippet();
            t1.snippet.playlistId = myChannel.Items.First().ContentDetails.RelatedPlaylists.WatchLater;
            t1.snippet.resourceId = new Entities.EntitiesRequest.Like.ResourceId { kind = "youtube#video", videoId = videoId };
            DataContractJsonSerializer jsondata = new DataContractJsonSerializer(typeof(Entities.EntitiesRequest.Like.SnippetLike));
            MemoryStream mem = new MemoryStream();
            jsondata.WriteObject(mem, t1);
            string josnserdata = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
            var tcs = new TaskCompletionSource<bool>();
            
            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post,petitionUri.ToString());

                Debug.WriteLine(string.Format("Request Content:{0}", josnserdata));
                request.Content = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(josnserdata.ToString())));
                HttpClient client = new HttpClient();
                client.DefaultRequestHeaders.Add("Authorization", "Bearer  " + token);
                request.Content.Headers.Add("Content-Type", "application/json");
                
                System.Net.Http.HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
                var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
           
                if (response.IsSuccessStatusCode)
                {
                    tcs.SetResult(true);
                }
                else
                {
                    tcs.SetResult(false);
                }
            }
            catch (Exception ex)
            {
                tcs.SetException(ex);
            }
       
            return await tcs.Task;         
          
        }

        public async Task<bool> InsertVideoToFavoritesAsync(string token, string videoId, CancellationTokenSource cancelTask)
        {
            channelProvider = new YoutubeChannelProvider();
            var myChannel = await channelProvider.GetMyChannelInfoAsync(token, cancelTask).ConfigureAwait(false);
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");
            petitionUri.AppendFormat("part={0}", "snippet");
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
            Entities.EntitiesRequest.Like.SnippetLike t1 = new Entities.EntitiesRequest.Like.SnippetLike();
            t1.snippet = new Entities.EntitiesRequest.Like.Snippet();
            t1.snippet.playlistId = myChannel.Items.First().ContentDetails.RelatedPlaylists.Favorites;
            t1.snippet.resourceId = new Entities.EntitiesRequest.Like.ResourceId { kind = "youtube#video", videoId = videoId };
            DataContractJsonSerializer jsondata = new DataContractJsonSerializer(typeof(Entities.EntitiesRequest.Like.SnippetLike));
            MemoryStream mem = new MemoryStream();
            jsondata.WriteObject(mem, t1);
            string josnserdata = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
            mem.Dispose();
             var tcs = new TaskCompletionSource<bool>();
            
            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post,petitionUri.ToString());

                Debug.WriteLine(string.Format("Request Content:{0}", josnserdata));
                request.Content = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(josnserdata.ToString())));
                HttpClient client = new HttpClient();
                client.DefaultRequestHeaders.Add("Authorization", "Bearer  " + token);
                request.Content.Headers.Add("Content-Type", "application/json");
                
                System.Net.Http.HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
                var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
           
                if (response.IsSuccessStatusCode)
                {
                    tcs.SetResult(true);
                }
                else
                {
                    tcs.SetResult(false);
                }
                client.Dispose();
                request.Dispose();
                responseContent = null;
            }
            catch (Exception ex)
            {
                tcs.SetException(ex);
            }
            josnserdata = null;
            josnserdata = null;
            mem.Dispose();
            return await tcs.Task;         
        
        }

        public async Task<PlayListItemQueryResult> GetPlayListInfoAsync(string playListId, string maxResults, CancellationTokenSource cancelTask)
        {
            StringBuilder petitionUri = new StringBuilder("https://www.googleapis.com/youtube/v3/playlistItems?");

            petitionUri.AppendFormat("part={0}", "contentDetails");
            petitionUri.AppendFormat("&playlistId={0}", playListId);
            petitionUri.AppendFormat("&mine={0}", "true");
            petitionUri.AppendFormat("&maxResults={0}", maxResults);
            petitionUri.AppendFormat("&key={0}", AppKeys.API_KEY);
               
            var taskCompletitionSource = new TaskCompletionSource<Entities.PlayListItemQuery.PlayListItemQueryResult>();
            return await ResolveRequest(petitionUri.ToString(), taskCompletitionSource, cancelTask);
        }
    
        private async Task<PlayListItemQueryResult> ResolveRequest(HttpWebRequest request, TaskCompletionSource<PlayListItemQueryResult> taskCompletitionSource, CancellationTokenSource cancelTask)
        {
            if (cancelTask == null)
            {
                cancelTask = new CancellationTokenSource();
            }
           
            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", request.Headers["Authorization"]);
                HttpResponseMessage response = await client.GetAsync(request.RequestUri.ToString(), cancelTask.Token).ConfigureAwait(false);
                
                string resultJson;
                using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), Encoding.UTF8))
                {
                    try
                    {
                        resultJson = await reader.ReadToEndAsync().ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(resultJson))
                        {
                            var entries = JsonConvert.DeserializeObject<PlayListItemQueryResult>(resultJson);

                            taskCompletitionSource.SetResult(entries);
                            resultJson = null;
                            entries = null;
                        }
                        else
                        {
                            taskCompletitionSource.SetResult(null);
                        }
                    }
                    catch (Exception ex)
                    {
                        taskCompletitionSource.SetException(ex);
                    }
                }
            }
            return await taskCompletitionSource.Task;
        }

        private async Task<PlayListItemQueryResult> ResolveRequest(string petition, TaskCompletionSource<PlayListItemQueryResult> taskCompletitionSource, CancellationTokenSource cancelTask)
        {
            if (cancelTask == null)
            {
                cancelTask = new CancellationTokenSource();
            }
            HttpWebRequest request = HttpWebRequest.CreateHttp(petition.ToString());
           
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(petition.ToString(), cancelTask.Token).ConfigureAwait(false);
                
                string resultJson;
                using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), Encoding.UTF8))
                {
                    try
                    {
                        resultJson = await reader.ReadToEndAsync().ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(resultJson))
                        {
                            var entries = JsonConvert.DeserializeObject<PlayListItemQueryResult>(resultJson);

                            taskCompletitionSource.SetResult(entries);
                            resultJson = null;
                            entries = null;
                        }
                        else
                        {
                            taskCompletitionSource.SetResult(null);
                        }
                        response.Dispose();
                    }
                    catch (Exception ex)
                    {
                        taskCompletitionSource.SetException(ex);
                    }
                }
            }
            return await taskCompletitionSource.Task;
        }
    }
}